package com.milling.common.utils.modbus;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.ip.IpParameters;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class ModbusMasterPoolFactory {

    private static final String MODBUS_HOST = "192.168.237.178"; // 替换为实际设备IP
    private static final int MODBUS_PORT = 502;               // Modbus TCP端口
    private static final int POOL_SIZE = 5;                   // 连接池大小

    private static volatile ModbusTcpService modbusTcpService;

    public static ModbusTcpService getModbusService() {
        if (modbusTcpService == null) {
            synchronized (ModbusMasterPoolFactory.class) {
                if (modbusTcpService == null) {
                    // 创建连接池
                    GenericObjectPool<ModbusMaster> pool =
                            ModbusMasterPoolFactory.createPool(MODBUS_HOST, MODBUS_PORT, POOL_SIZE);

                    // 初始化服务实例
                    modbusTcpService = new ModbusTcpServiceImpl(pool);
                }
            }
        }
        return modbusTcpService;
    }

    public static GenericObjectPool<ModbusMaster> createPool(String host, int port, int poolSize) {
        ModbusFactory modbusFactory = new ModbusFactory();
        IpParameters ipParameters = new IpParameters();
        ipParameters.setHost(host);
        ipParameters.setPort(port);

        GenericObjectPoolConfig<ModbusMaster> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(poolSize);

        return new GenericObjectPool<>(new BasePooledObjectFactory<ModbusMaster>() {
            @Override
            public ModbusMaster create() throws ModbusInitException {
                return modbusFactory.createTcpMaster(ipParameters, true);
            }

            @Override
            public PooledObject<ModbusMaster> wrap(ModbusMaster modbusMaster) {
                return new DefaultPooledObject<>(modbusMaster);
            }

            @Override
            public void destroyObject(PooledObject<ModbusMaster> p) throws Exception {
                p.getObject().destroy();
            }
        }, config);
    }
}
